package com.ruoyi.binance.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.binance.api.OrderApi;
import com.ruoyi.binance.domain.Binance15macd;
import com.ruoyi.binance.domain.Binance15minDayAve;
import com.ruoyi.binance.domain.BinanceTransactionConf;
import com.ruoyi.binance.domain.BinanceTransactionOrder;
import com.ruoyi.binance.mapper.Binance15macdMapper;
import com.ruoyi.binance.mapper.Binance15minDayAveMapper;
import com.ruoyi.binance.mapper.BinanceTransactionConfMapper;
import com.ruoyi.binance.mapper.BinanceTransactionOrderMapper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;

@Component
public class Async15MACD {
    @Autowired
    private BinanceTransactionOrderMapper binanceTransactionOrderMapper;
    @Autowired
    private BinanceTransactionConfMapper binanceTransactionConfMapper;
    @Autowired
    private Binance15macdMapper binance15macdMapper;
    @Autowired
    private Binance15minDayAveMapper binance15minDayAveMapper;

    private final Map<String, LinkedList<BigDecimal>> macdMap = new HashMap<>();
    /**
     * 检查连续N次的bar值是否同为正数或负数
     *
     * @param code 交易对代码
     * @param count 检查次数
     * @return 是否满足连续条件
     */
    private boolean checkConsecutiveBars(String code, BigDecimal bar, int count) {
        LinkedList<BigDecimal> bigDecimals = macdMap.get(code);
        if (bigDecimals == null){
            macdMap.put(code, new LinkedList<BigDecimal>());
            macdMap.get(code).add(bar);
        }else if (bigDecimals.size() < count) {
            bigDecimals.add(bar);
        }else if (bigDecimals.size() == count) {
            bigDecimals.removeFirst();
            bigDecimals.add(bar);
        }

        if (bigDecimals == null || bigDecimals.size() < count) {
            return false; // 数据不足
        }

        // 检查是否全部为正数或全部为负数
        boolean allPositive = true;
        boolean allNegative = true;

        for (BigDecimal b : bigDecimals) {
            if (b.compareTo(BigDecimal.ZERO) < 0) {
                allPositive = false;
            }
            if (b.compareTo(BigDecimal.ZERO) > 0) {
                allNegative = false;
            }
        }
        return allPositive || allNegative;
    }


    @Async
    public void getAPriceMonitoring(Long confId, String code, Date time, BigDecimal close, BigDecimal open) {
        //获取当前时间内的15分钟MACD
        Binance15macd binance15macd = binance15macdMapper.selectBinance15macdByCodeAndTime(code, DateUtil.format(time, DatePattern.NORM_DATETIME_FORMAT));
        if (binance15macd == null) {
            return;
        }
        //连续20次的bar值都为正数或者都为负数,可以作为稳定值
        boolean consecutiveBarsCondition = checkConsecutiveBars(code, binance15macd.getBar(), 28);
        if(!consecutiveBarsCondition){
            return;
        }
        Binance15minDayAve binance15minDayAve = binance15minDayAveMapper.selectBinance15minDayAveByCodeAndTime(code, DateUtils.getFormatTime(time));
        BigDecimal averagePriceDay = binance15minDayAve.getPrice();
        //收盘价大于等于日均价 为多行情
        if (close.compareTo(averagePriceDay) >= 0) {
            //bar大于0 进行买入
            if (binance15macd.getBar().compareTo(BigDecimal.ZERO) > 0) {
                //进行下单
                BinanceTransactionConf binanceTransactionConf = binanceTransactionConfMapper.selectBinanceTransactionConfById(confId);
                if (binanceTransactionConf != null && binanceTransactionConf.getUsdtNumber().compareTo(BigDecimal.ZERO) > 0
                        && !"BUY".equals(binanceTransactionConf.getSide())) {

                    BinanceTransactionConf bean = new BinanceTransactionConf();
                    bean.setId(binanceTransactionConf.getId());
                    bean.setSide("BUY");
                    binanceTransactionConfMapper.updateBinanceTransactionConf(bean);

                    BinanceTransactionOrder order = new BinanceTransactionOrder();
                    order.setCode(code);
                    order.setOrgOrderId(IdUtil.getSnowflakeNextIdStr());
                    order.setQuoteOrderQty(binanceTransactionConf.getUsdtNumber());
                    order.setSide("BUY");
                    order.setType("MARKET");
                    order.setConfigId(confId);
                    order.setCreateTime(time);
                    order.setRemark("自动交易");
                    int save = binanceTransactionOrderMapper.insertBinanceTransactionOrder(order);
                    if (save > 0) {
                        //调用下单接口
                        JSONObject res = OrderApi.order(order);
                        if (StringUtils.isNotBlank(res.getString("code"))) {
                            order.setStatus("REJECTED");
                            order.setRemark(res.getString("msg"));
                        } else {
                            order.setStatus("PENDING_NEW");
                            order.setOrderId(res.getString("orderId"));
                        }
                        binanceTransactionOrderMapper.updateBinanceTransactionOrder(order);
                    }
                }
            }
        }
        //bar小于0 进行卖出
        if (binance15macd.getBar().compareTo(BigDecimal.ZERO) < 0) {
            //进行下单
            BinanceTransactionConf binanceTransactionConf = binanceTransactionConfMapper.selectBinanceTransactionConfById(confId);
            if (binanceTransactionConf != null && binanceTransactionConf.getCoinNumber().compareTo(BigDecimal.ZERO) > 0
                    && !"SELL".equals(binanceTransactionConf.getSide())) {

                BinanceTransactionConf bean = new BinanceTransactionConf();
                bean.setId(binanceTransactionConf.getId());
                bean.setSide("SELL");
                binanceTransactionConfMapper.updateBinanceTransactionConf(bean);

                BinanceTransactionOrder order = new BinanceTransactionOrder();
                order.setCode(code);
                order.setOrgOrderId(IdUtil.getSnowflakeNextIdStr());
                order.setQuantity(binanceTransactionConf.getCoinNumber());
                order.setSide("SELL");
                order.setType("MARKET");
                order.setConfigId(confId);
                order.setCreateTime(time);
                order.setRemark("自动交易");
                int save = binanceTransactionOrderMapper.insertBinanceTransactionOrder(order);
                if (save > 0) {
                    //调用下单接口
                    JSONObject res = OrderApi.order(order);
                    if (StringUtils.isNotBlank(res.getString("code"))) {
                        order.setStatus("REJECTED");
                        order.setRemark(res.getString("msg"));
                    } else {
                        order.setStatus("PENDING_NEW");
                        order.setOrderId(res.getString("orderId"));
                    }
                    binanceTransactionOrderMapper.updateBinanceTransactionOrder(order);
                }
            }
        }
    }
}
